package com.woniuxy.bookmall.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.woniuxy.bookmall.entity.TItem;
import com.woniuxy.bookmall.entity.TOrder;
import com.woniuxy.bookmall.entity.TUser;
import com.woniuxy.bookmall.exceptions.OrderSubmitFailException;
import com.woniuxy.bookmall.exceptions.UnderStockException;
import com.woniuxy.bookmall.mapper.TBookMapper;
import com.woniuxy.bookmall.mapper.TItemMapper;
import com.woniuxy.bookmall.mapper.TOrderMapper;
import com.woniuxy.bookmall.utils.RedisUtils;
import com.woniuxy.bookmall.vo.Book;
import com.woniuxy.bookmall.vo.Cart;
import com.woniuxy.bookmall.vo.OrderVo;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.spring.annotation.MapperScan;

import java.math.BigDecimal;
import java.sql.Array;
import java.util.*;

@Service
public class OrderService {
    public static final String ORDER_NORMAL_EXCHANGE = "order_normal_exchange" ;
    public static final String ORDER_NORMAL_ROUTING_KEY = "order_normal_routing_key" ;

    @Autowired
    TBookMapper bookMapper ;
    @Autowired
    TOrderMapper orderMapper ;

    @Autowired
    TItemMapper itemMapper ;

    @Autowired
    RedisUtils redisUtils ;

    @Autowired
    RabbitTemplate rabbitTemplate ;

    @Transactional
    public Long submitOrder(Long addressId, Long[] bookId, TUser user) throws JsonProcessingException {
        // 获取一个 订单的 id  处理幂等性 问题

        String key = "WONIU"+user.getId();
        //0.查询出 所有的商品对象  redis
        String[] bids = new String[bookId.length];
        for (int i=0;i<bookId.length;i++) {
            bids[i] = bookId[i]+"";
        }
        List<Object> objects = redisUtils.multiGet(key, Arrays.asList(bids));
        List<Cart> carts = new ArrayList<>();
        //用于发送mq消息的图书数据
        List<Book> books = new ArrayList<>();
        for (Object o :objects) {
            Cart c = (Cart) o;
            carts.add(c);
            Book book = new Book();
            book.setId(c.getBookid());
            book.setBuyCount(c.getBcount());
            books.add(book);
        }
        // 1. 减库存
        for (Cart c :carts) {
            int i = bookMapper.updateStoreCountById(c.getBookid(),c.getBcount());
            if (i < 1) {
                throw new UnderStockException("当前商品【"+c.getBookname()+"】库存不足,当前库存");
            }
        }
        // 2. 保存订单
        TOrder order = new TOrder();
        order.setAddressid(addressId);
        order.setCreatetime(new Date());
        order.setState(0);
        order.setOrdernum("WONIU"+System.currentTimeMillis());
        order.setUserid(user.getId());
        BigDecimal all = new BigDecimal("0");
        for (Cart c :carts) {
            all = all.add(c.getSumprice());
        }
        order.setTotalprice(all);
        //生成一个ID  自定义类型    处理幂等性
        int i = orderMapper.insert(order);
        if (i < 1) {
            throw new OrderSubmitFailException("下单失败!");
        }
        // 3. 保存订单明细
        List<TItem> items = new ArrayList<>();
        for (Cart c :carts) {
            TItem item = new TItem();
            item.setSumprice(c.getSumprice());
            item.setBcount(c.getBcount());
            item.setPrice(c.getPrice());
            item.setBookname(c.getBookname());
            item.setOrderid(order.getId());
            item.setBookid(c.getBookid());
            items.add(item);
        }
        //保存
        int nums = itemMapper.insertBatch(items);
        if (nums < items.size()) {
            throw new OrderSubmitFailException("下单失败!");
        }
        //4. 更新销量
        for (Cart c :carts) {
            int k = bookMapper.updateBuycountById(c.getBookid(),c.getBcount());
        }
        //3. 删除购物城中这些商品
        redisUtils.hdel(key,bids);

        //发送MQ消息
        Map<String,Object> maps = new HashMap<>();
        maps.put("orderNum",order.getOrdernum());
        ObjectMapper objectMapper = new ObjectMapper();
        String bookJson = objectMapper.writeValueAsString(books);
        maps.put("bookMsg",bookJson);

        //发送
        rabbitTemplate.convertAndSend(ORDER_NORMAL_EXCHANGE,ORDER_NORMAL_ROUTING_KEY,maps);

        //向redis中存储一个 时间 对当前的订单编号
        redisUtils.set(order.getOrdernum(), maps,5*60);
        return order.getId();
    }

    public OrderVo findOrderById(Long orderId) {
        return orderMapper.selectOrderByKey(orderId);
    }

    public void modifyOrderOfStatus(String orderNum) {
        orderMapper.updateOrderOfStatus(orderNum);
    }
}